package com.intertid.mongodb

import com.intertid.mongodb.factory.MongoDBTemplateFactory
import com.intertid.mongodb.error._
import com.intertid.mongodb.commons.MongoDBUtils
import com.mongodb.casbah.Imports._;
import scala.reflect.BeanProperty

class DaoSupport[PK <: Object: Manifest, BEAN <: Object: Manifest](_template: MongoDBTemplate) {

  def this() = this(null);

  @BeanProperty
  var template: MongoDBTemplate = _template;

  def currentTemplate = _template;

  protected val beanClass = manifest[BEAN].erasure;

  protected val collectionName = if (!Mapper.exists(beanClass)) dberror(MongoDBErrorDefine.ENTITY_DEFINE_NOT_FOUND) else Mapper.getCollectionName(beanClass);

  def +=(bean: BEAN): BEAN = (_template += bean).asInstanceOf[BEAN];

  def *=(beans: BEAN*): Unit = (_template *= (beans: _*))

  def -=(bean: BEAN): Unit = (_template -= bean)

  def /=(beans: BEAN*): Unit = (_template /= (beans: _*))

  def ->(id: PK): Option[BEAN] = {

    val dbobj = (_template(collectionName) findOneByID (if (id.isInstanceOf[String]) new ObjectId(id.asInstanceOf[AnyRef].toString()) else id.asInstanceOf[AnyRef]));
    return if (!dbobj.isEmpty) Some(MongoDBUtils.dbObject2Bean(dbobj.get).asInstanceOf[BEAN]) else None;
  }

  def ->(query: DBObject): List[BEAN] = {
    val cur = _template(collectionName).find(query);
    var list: List[BEAN] = Nil;
    while (cur.hasNext) {
      val dbobj = cur.next();
      list = list ::: List(MongoDBUtils.dbObject2Bean(dbobj).asInstanceOf[BEAN]);
    }
    list
  }

  def ::(query: DBObject): Option[BEAN] = {
    val dbobj = _template(collectionName).findOne(query);

    println("collectionName:" + collectionName);
    println(query);
    if (dbobj.isEmpty) None else Some(MongoDBUtils.dbObject2Bean(dbobj.get).asInstanceOf[BEAN])
  }

  def count(query: DBObject): Long = {
    _template(collectionName).count(query);
  }

}